﻿Imports System
Imports System.Data
Imports System.Data.Common
Imports System.Threading
Imports System.Transactions
Imports System.Workflow.Runtime

Namespace System.Workflow.Runtime.Hosting
    Friend NotInheritable Class LocalTransaction
        Implements IPromotableSinglePhaseNotification, ITransactionPromoter
        ' Methods
        Friend Sub New(ByVal dbHelper As DbResourceAllocator, ByVal handle As ManualResetEvent)
            If (handle Is Nothing) Then
                Throw New ArgumentNullException("handle")
            End If
            Me.connection = dbHelper.OpenNewConnectionNoEnlist
            Me.transaction = Me.connection.BeginTransaction
            Me.handle = handle
        End Sub

        Public Sub Initialize()
        End Sub

        Public Function Promote() As Byte()
            Throw New TransactionPromotionException(ExecutionStringManager.PromotionNotSupported)
        End Function

        Public Sub Rollback(ByVal en As SinglePhaseEnlistment)
            If (en Is Nothing) Then
                Throw New ArgumentNullException("en")
            End If
            Try 
                Me.handle.WaitOne
            Catch exception1 As ObjectDisposedException
            End Try
            SyncLock Me.syncRoot
                If (Not Me.transaction Is Nothing) Then
                    Me.transaction.Dispose
                End If
                If ((Not Me.connection Is Nothing) AndAlso (Me.connection.State <> ConnectionState.Closed)) Then
                    Me.connection.Close
                    Me.connection = Nothing
                End If
                en.Aborted
            End SyncLock
        End Sub

        Public Sub SinglePhaseCommit(ByVal en As SinglePhaseEnlistment)
            If (en Is Nothing) Then
                Throw New ArgumentNullException("en")
            End If
            Try 
                Me.handle.WaitOne
            Catch exception1 As ObjectDisposedException
            End Try
            SyncLock Me.syncRoot
                Try 
                    Me.transaction.Commit
                    en.Committed
                Catch exception As Exception
                    en.Aborted(exception)
                Finally
                    If ((Not Me.connection Is Nothing) AndAlso (Me.connection.State <> ConnectionState.Closed)) Then
                        Me.connection.Close
                        Me.connection = Nothing
                    End If
                End Try
            End SyncLock
        End Sub


        ' Properties
        Public ReadOnly Property Connection As DbConnection
            Get
                Return Me.connection
            End Get
        End Property

        Public ReadOnly Property Transaction As DbTransaction
            Get
                Return Me.transaction
            End Get
        End Property


        ' Fields
        Private connection As DbConnection
        Private handle As ManualResetEvent
        Private syncRoot As Object = New Object
        Private ReadOnly transaction As DbTransaction
    End Class
End Namespace

